<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Chapter 20 InnoDB Cluster</title>
<link rel="stylesheet" href="mvl.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets + chunker.py v1.9.2" />
<link rel="start" href="index.html" title="{book-title}" />
<link rel="up" href="" title="" />
<link rel="prev" href="document-store.html" title="Chapter 19 Using MySQL as a Document Store" />
<link rel="next" href="mysql-cluster.html" title="Chapter 21 MySQL NDB Cluster 7.5 and NDB Cluster 7.6" />
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 20 InnoDB Cluster</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="document-store.html">Prev</a> </td>
<th width="60%" align="center"></th>
<td width="20%" align="right"> <a accesskey="n" href="mysql-cluster.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="chapter">
<div class="titlepage">
<div>
<div>
<h1 class="title"><a name="mysql-innodb-cluster-userguide"></a>Chapter 20 InnoDB Cluster</h1>

</div>

</div>

</div>
<div class="toc">
<p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-introduction">20.1 Introducing InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-creating">20.2 Creating an InnoDB Cluster</a></span></dt><dd><dl><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-deployment-methods">20.2.1 Deployment Scenarios</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-requirements">20.2.2 InnoDB Cluster Requirements</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-methods-installing">20.2.3 Methods of Installing</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-sandbox-deployment">20.2.4 Sandbox Deployment of InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-deployment">20.2.5 Production Deployment of InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-from-group-replication">20.2.6 Adopting a Group Replication Deployment</a></span></dt></dl></dd><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-using-router">20.3 Using MySQL Router with InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-working-with-cluster">20.4 Working with InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-limitations">20.5 Known Limitations</a></span></dt></dl>
</div>
<p>
    This chapter covers MySQL InnoDB cluster, which combines MySQL
    technologies to enable you to create highly available clusters of
    MySQL server instances.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-introduction"></a>20.1 Introducing InnoDB Cluster</h2>
</div>
</div>
</div>
<p>
      MySQL InnoDB cluster provides a complete high availability
      solution for MySQL.
      <a class="link" href="mysql-shell.html" title="Chapter 18 MySQL Shell User Guide">MySQL Shell</a> includes
      AdminAPI which enables you to easily configure and
      administer a group of at least three MySQL server instances to
      function as an InnoDB cluster. Each MySQL server instance runs
      MySQL Group Replication, which provides the mechanism to
      replicate data within InnoDB clusters, with built-in failover.
      AdminAPI removes the need to work directly with Group
      Replication in InnoDB clusters, but for more information see
      <a class="xref" href="group-replication.html" title="Chapter 17 Group Replication">Chapter 17, <i>Group Replication</i></a> which explains the details.
      <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/" target="_top">MySQL Router</a> can automatically
      configure itself based on the cluster you deploy, connecting
      client applications transparently to the server instances. In the
      event of an unexpected failure of a server instance the cluster
      reconfigures automatically. In the default single-primary mode, an
      InnoDB cluster has a single read-write server instance - the
      primary. Multiple secondary server instances are replicas of the
      primary. If the primary fails, a secondary is automatically
      promoted to the role of primary. MySQL Router detects this and
      forwards client applications to the new primary. Advanced users
      can also configure a cluster to have multiple-primaries.

      
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
        InnoDB cluster does not provide support for MySQL NDB Cluster.
        NDB Cluster depends on the <a class="link" href="mysql-cluster.html" title="Chapter 21 MySQL NDB Cluster 7.5 and NDB Cluster 7.6"><code class="literal">NDB</code></a> storage
        engine as well as a number of programs specific to NDB Cluster which
        are not furnished with MySQL Server 5.7;
        <code class="literal">NDB</code> is available only as part of the MySQL
        NDB Cluster distribution. In addition, the MySQL server binary
        (<a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>) that is supplied with MySQL Server
        5.7 cannot be used with NDB Cluster. For more
        information about MySQL NDB Cluster, see
        <a class="xref" href="mysql-cluster.html" title="Chapter 21 MySQL NDB Cluster 7.5 and NDB Cluster 7.6">Chapter 21, <i>MySQL NDB Cluster 7.5 and NDB Cluster 7.6</i></a>.
        <a class="xref" href="mysql-cluster.html#mysql-cluster-compared" title="21.1.5 MySQL Server Using InnoDB Compared with NDB Cluster">Section 21.1.5, “MySQL Server Using InnoDB Compared with NDB Cluster”</a>, provides information
        about the differences between the <code class="literal">InnoDB</code> and
        <code class="literal">NDB</code> storage engines.
</p>
</div>
<p>
      The following diagram shows an overview of how these technologies
      work together:
</p>
<div class="figure">
<a name="innodb-cluster-overview-image"></a><p class="title"><b>Figure 20.1 InnoDB cluster overview</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/innodb_cluster_overview.png" width="600" height="753" alt="Three MySQL servers are grouped together as a high availability cluster. One of the servers is the read/write primary instance, and the other two are read-only secondary instances. Group Replication is used to replicate data from the primary instance to the secondary instances. MySQL Router connects client applications (in this example, a MySQL Connector) to the primary instance. The cluster admin capability in MySQL Shell can connect directly to the primary instance using the MySQL X AdminAPI, or it can connect through MySQL Router like other client applications.">
</div>

</div>

</div>
<br class="figure-break">
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h3 class="title"><a name="admin-api"></a>Using AdminAPI</h3>

</div>

</div>

</div>
<p>
        MySQL Shell includes the AdminAPI, which is accessed
        through the <code class="literal">dba</code> global variable and its
        associated methods. The <code class="literal">dba</code> variable's
        methods enable you to deploy, configure, and administer InnoDB
        clusters. For example, use the
        <code class="literal">dba.createCluster()</code> method to create an
        InnoDB cluster.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          MySQL Shell enables you to connect to servers over a socket
          connection, but AdminAPI requires TCP connections to a
          server instance. Do not use socket based connections with
          AdminAPI.
</p>
</div>
<p>
        MySQL Shell provides online help for the AdminAPI. To
        list all available <code class="literal">dba</code> commands, use the
        <code class="literal">dba.help()</code> method. For online help on a
        specific method, use the general format
        <code class="literal">object.help('methodname')</code>. For example:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>dba.help('getCluster')</code></strong>

Retrieves a cluster from the Metadata Store.

SYNTAX
  &lt;Dba&gt;.getCluster([name])

WHERE
  name: Parameter to specify the name of the cluster to be returned.

DESCRIPTION

If name is not specified, the default cluster will be returned.

If name is specified, and no cluster with the indicated name is found, an error
will be raised.
</pre>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-creating"></a>20.2 Creating an InnoDB Cluster</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-deployment-methods">20.2.1 Deployment Scenarios</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-requirements">20.2.2 InnoDB Cluster Requirements</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-methods-installing">20.2.3 Methods of Installing</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-sandbox-deployment">20.2.4 Sandbox Deployment of InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-deployment">20.2.5 Production Deployment of InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-from-group-replication">20.2.6 Adopting a Group Replication Deployment</a></span></dt></dl>
</div>
<p>
      This section explains the different ways you can create an
      InnoDB cluster, the requirements for server instances and the
      software you need to install to deploy a cluster.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-deployment-methods"></a>20.2.1 Deployment Scenarios</h3>
</div>
</div>
</div>
<p>
        InnoDB cluster supports the following deployment scenarios:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <span class="emphasis"><em>Sandbox deployment:</em></span> if you want to test
            out InnoDB cluster before committing to a full production
            deployment, the provided sandbox feature enables you to
            quickly set up a cluster on your local machine. Sandbox
            server instances are created with the required configuration
            and you can experiment with InnoDB cluster to become
            familiar with the technologies employed. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-sandbox-deployment" title="20.2.4 Sandbox Deployment of InnoDB Cluster">Section 20.2.4, “Sandbox Deployment of InnoDB Cluster”</a>
            for instructions.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Production deployment:</em></span> if you want to
            use InnoDB cluster in a full production environment you
            need to configure the required number of machines and then
            deploy your server instances to the machines. A production
            deployment enables you to exploit the high availability
            features of InnoDB cluster to their full potential. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-deployment" title="20.2.5 Production Deployment of InnoDB Cluster">Section 20.2.5, “Production Deployment of InnoDB Cluster”</a>
            for instructions.
</p></li></ul>
</div>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Important
</div>
<p>
          A sandbox deployment is not suitable for use in a full
          production environment.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-requirements"></a>20.2.2 InnoDB Cluster Requirements</h3>

</div>

</div>

</div>
<p>
        Before installing a production deployment of InnoDB cluster,
        ensure that the server instances you intend to use meet the
        following requirements.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            InnoDB cluster uses Group Replication and therefore your
            server instances must meet the same requirements. See
            <a class="xref" href="group-replication.html#group-replication-requirements" title="17.7.1 Group Replication Requirements">Section 17.7.1, “Group Replication Requirements”</a>.
            AdminAPI provides the
            <code class="literal">dba.checkInstanceConfiguration()</code> method
            to verify that an instance meets the Group Replication
            requirements, and the
            <code class="literal">dba.configureLocalInstance()</code> method to
            configure an instance to meet the requirements.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
              When using a sandbox deployment the instances are
              configured to meet these requirements automatically.
</p>
</div>
</li><li class="listitem"><p>
            The provisioning scripts that MySQL Shell uses to
            configure servers for use in InnoDB cluster require access
            to Python version 2.7. For a sandbox deployment Python is
            required on the single machine used for the deployment,
            production deployments require Python on each server
            instance.
          </p><p>
            On Windows MySQL Shell includes Python and no user
            configuration is required. On Unix Python must be found as
            part of the shell environment. To check that your system has
            Python configured correctly issue:
          </p><pre data-lang="terminal" class="programlisting">$ <strong class="userinput"><code>/usr/bin/env python</code></strong></pre><p>
            If a Python interpreter starts, no further action is
            required. If the previous command fails, create a soft link
            between <code class="literal">/usr/bin/python</code> and your chosen
            Python binary.
</p></li></ul>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-methods-installing"></a>20.2.3 Methods of Installing</h3>

</div>

</div>

</div>
<p>
        The method you use to install InnoDB cluster depends on the
        type of deployment you intend to use. For a sandbox deployment
        install the components of InnoDB cluster to a single machine.
        A sandbox deployment is local to a single machine, therefore the
        install needs to only be done once on the local machine.
        Similarly there is no need to connect to the instances
        individually for configuration, the sandbox instances are local.
        For a production deployment install the components to each
        machine that you intend to add to your cluster. A production
        deployment uses multiple remote host machines running MySQL
        server instances, so you need to connect to each machine using a
        tool such as SSH or Windows remote desktop to carry out tasks
        such as installing components and configuring the server
        instance. The following methods of installing InnoDB cluster
        are available:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Downloading and installing the components using the
            following documentation:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                MySQL Server - see <a class="xref" href="installing.html" title="Chapter 2 Installing and Upgrading MySQL">Chapter 2, <i>Installing and Upgrading MySQL</i></a>.
              </p></li><li class="listitem"><p>
                MySQL Shell - see
                <a class="xref" href="document-store.html#document-store-shell-install" title="19.3.1 Installing MySQL Shell">Section 19.3.1, “Installing MySQL Shell”</a>.
              </p></li><li class="listitem"><p>
                MySQL Router - see
                <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysql-router-installation.html" target="_top">Installing MySQL Router</a>.
</p></li></ul>
</div>
</li><li class="listitem"><p>
            On Windows you can use the MySQL Installer for Windows for a
            sandbox deployment. For details, see
            <a class="xref" href="installing.html#mysql-installer-workflow-innodb-cluster" title="2.3.3.2.1 Group Replication">Section 2.3.3.2.1, “Group Replication”</a>.
</p></li></ul>
</div>
<p>
        Once you have installed the software required by
        InnoDB cluster choose to follow either
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-sandbox-deployment" title="20.2.4 Sandbox Deployment of InnoDB Cluster">Section 20.2.4, “Sandbox Deployment of InnoDB Cluster”</a> or
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-deployment" title="20.2.5 Production Deployment of InnoDB Cluster">Section 20.2.5, “Production Deployment of InnoDB Cluster”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-sandbox-deployment"></a>20.2.4 Sandbox Deployment of InnoDB Cluster</h3>

</div>

</div>

</div>
<p>
        This section explains how to set up a sandbox InnoDB cluster
        deployment. You create and administer your InnoDB clusters using
        MySQL Shell with the included AdminAPI. This section assumes
        familiarity with MySQL Shell, see
        <a class="xref" href="mysql-shell.html" title="Chapter 18 MySQL Shell User Guide">Chapter 18, <i>MySQL Shell User Guide</i></a> for further information.
      </p><p>
        Initially deploying and using local sandbox instances of MySQL
        is a good way to start your exploration of InnoDB cluster. You
        can fully test out InnoDB cluster locally, prior to deployment
        on your production servers. MySQL Shell has built-in
        functionality for creating sandbox instances that are correctly
        configured to work with Group Replication in a locally deployed
        scenario.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          Sandbox instances are only suitable for deploying and running
          on your local machine for testing purposes. In a production
          environment the MySQL Server instances are deployed to various
          host machines on the network. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-deployment" title="20.2.5 Production Deployment of InnoDB Cluster">Section 20.2.5, “Production Deployment of InnoDB Cluster”</a>
          for more information.
</p>
</div>
<p>
        This tutorial shows how to use MySQL Shell to create an
        InnoDB cluster consisting of three MySQL server instances.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#deploy-sandbox-instances" title="Deploying Sandbox Instances">Deploying Sandbox Instances</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#create-innodb-cluster" title="Creating the Sandbox InnoDB Cluster">Creating the Sandbox InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#add-instances-innodb-cluster" title="Adding Instances to an InnoDB Cluster">Adding Instances to an InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#persist-configuration-innodb-cluster" title="Persisting the Configuration">Persisting the Configuration</a></p></li></ul>
</div>

<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="deploy-sandbox-instances"></a>Deploying Sandbox Instances</h4>

</div>

</div>

</div>
<p>
          MySQL Shell includes the AdminAPI that adds the
          <code class="literal">dba</code> global variable, which provides
          functions for administration of sandbox instances. In this
          example setup, you create three sandbox instances using
          <code class="literal">dba.deploySandboxInstance()</code>.
        </p><p>
          Start MySQL Shell from a command prompt by issuing the
          command:
        </p><pre data-lang="terminal" class="programlisting">
shell&gt; <strong class="userinput"><code>mysqlsh</code></strong>
</pre><p>
          MySQL Shell provides two scripting language modes,
          JavaScript and Python, in addition to a native SQL mode.
          Throughout this guide MySQL Shell is used primarily in
          JavaScript mode

          

          . When MySQL Shell starts it is in JavaScript mode by
          default. Switch modes by issuing <code class="literal">\js</code> for
          JavaScript mode, <code class="literal">\py</code> for Python mode, and
          <code class="literal">\sql</code> for SQL mode. Ensure you are in
          JavaScript mode by issuing the <code class="literal">\js</code> command,
          then execute:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>dba.deploySandboxInstance(3310)</code></strong>
</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            Terminating commands with a semi-colon is not required in
            JavaScript and Python modes.
</p>
</div>
<p>
          The argument passed to
          <code class="literal">deploySandboxInstance()</code> is the TCP port
          number where the MySQL Server instance listens for
          connections. By default the sandbox is created in a directory
          named
          <code class="literal">$HOME/mysql-sandboxes/<em class="replaceable"><code>port</code></em></code>
          on Unix systems. For Microsoft Windows systems the directory
          is
          <code class="literal">%userprofile%\MySQL\mysql-sandboxes\<em class="replaceable"><code>port</code></em></code>.
        </p><p>
          The root password for the instance is prompted for.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
            Each instance has its own password. Defining the same
            password for all sandboxes in this tutorial makes it easier,
            but remember to use different passwords for each instance in
            production deployments.
</p>
</div>
<p>
          To deploy further sandbox server instances, repeat the steps
          followed for the sandbox instance at port 3310, choosing
          different port numbers. For each additional sandbox instance
          issue:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>dba.deploySandboxInstance(<em class="replaceable"><code>port_number</code></em>)</code></strong>
</pre><p>
          To follow this tutorial, use port numbers 3310, 3320 and 3330
          for the three sandbox server instances. Issue:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>dba.deploySandboxInstance(<em class="replaceable"><code>3320</code></em>)</code></strong>
mysql-js&gt; <strong class="userinput"><code>dba.deploySandboxInstance(<em class="replaceable"><code>3330</code></em>)</code></strong>
</pre>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="create-innodb-cluster"></a>Creating the Sandbox InnoDB Cluster</h4>

</div>

</div>

</div>
<p>
          The next step is to create the InnoDB cluster while
          connected to the seed MySQL Server instance. The seed instance
          contains the data that you want to replicate to the other
          instances. In this example the sandbox instances are blank,
          therefore we can choose any instance.
        </p><p>
          Connect MySQL Shell to the seed instance, in this case the
          one at port 3310:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>\connect root@localhost:3310</code></strong></pre><p>
          The <code class="literal">\connect</code> MySQL Shell command is a
          shortcut for the <code class="literal">shell.connect()</code> method:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>shell.connect('root@localhost:3310')</code></strong>
</pre><p>
          Once you have connected, AdminAPI can write to the local
          instance's option file. This is different to working with
          a production deployment, where you would need to connect to
          the remote instance and run the MySQL Shell application
          locally on the instance before AdminAPI can write to
          the instance's option file.
        </p><p>
          Use the <code class="literal">dba.createCluster()</code> method to
          create the InnoDB cluster with the currently connected
          instance as the seed:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>var cluster = dba.createCluster('testCluster')</code></strong>
</pre><p>
          The <code class="literal">createCluster()</code> method deploys the
          InnoDB cluster metadata to the selected instance, and adds
          the instance you are currently connected to as the seed
          instance. The <code class="literal">createCluster()</code> method
          returns the created cluster, in the example above this is
          assigned to the <code class="literal">cluster</code> variable. The
          parameter passed to the <code class="literal">createCluster()</code>
          method is a symbolic name given to this InnoDB cluster, in
          this case <code class="literal">testCluster</code>.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            If the instance has
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
            might need to confirm that AdminAPI can set
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
            information.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="add-instances-innodb-cluster"></a>Adding Instances to an InnoDB Cluster</h4>

</div>

</div>

</div>
<p>
          The next step is to add more instances to the
          InnoDB cluster. Any transactions that were executed by the
          seed instance are re-executed by each secondary instance as it
          is added. This tutorial uses the sandbox instances that were
          created earlier at ports 3320 and 3330.
        </p><p>
          The seed instance in this example was recently created, so it
          is nearly empty. Therefore, there is little data that needs to
          be replicated from the seed instance to the secondary
          instances. In a production environment, where you have an
          existing database on the seed instance, you could use a tool
          such as MySQL Enterprise Backup to ensure that the secondaries have matching
          data before replication starts. This avoids the possibility of
          lengthy delays while data replicates from the primary to the
          secondaries. See
          <a class="xref" href="group-replication.html#group-replication-enterprise-backup" title="17.4.4 Using MySQL Enterprise Backup with Group Replication">Section 17.4.4, “Using MySQL Enterprise Backup with Group Replication”</a>.
        </p><p>
          Add the second instance to the InnoDB cluster:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>cluster.addInstance('root@localhost:3320')</code></strong>
</pre><p>
          The root user's password is prompted for.
        </p><p>
          Add the third instance:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>cluster.addInstance('root@localhost:3330')</code></strong>
</pre><p>
          The root user's password is prompted for.
        </p><p>
          At this point you have created a cluster with three instances:
          a primary, and two secondaries.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            You can only specify <code class="literal">localhost</code> in
            <code class="literal">addInstance()</code> if the instance is a
            sandbox instance. This also applies to the implicit
            <code class="literal">addInstance()</code> after issuing
            <code class="literal">createCluster()</code>.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="persist-configuration-innodb-cluster"></a>Persisting the Configuration</h4>

</div>

</div>

</div>
<p>
          Once the sandbox instances have been added to the cluster, the
          configuration required for InnoDB cluster must be persisted
          to each of the instance's option files. Connect to each
          instance.
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>\connect <em class="replaceable"><code>instance</code></em></code></strong></pre><p>
          Issue
          <code class="literal">dba.configureLocalInstance(<em class="replaceable"><code>instance</code></em>)</code>.
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>dba.configureLocalInstance('<em class="replaceable"><code>instance</code></em>')</code></strong>
</pre><p>
          You are prompted for the instance's password. The
          configuration changes are persisted to the instance.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
            If <code class="literal">dba.configureLocalInstance()</code> is not
            issued when connected to the instance, the configuration is
            not persisted to the option file. This does not stop the
            instance from initially joining a cluster, but it does mean
            that the instance cannot rejoin the cluster automatically,
            for example after being stopped.
</p>
</div>
<p>
          Repeat the process of connecting to each sandbox instance you
          added to the cluster and persisting the configuration. For
          this example we added sandbox instances at ports 3310, 3320
          and 3330. Therefore issue this for ports 3320 and 3330:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>\connect root@localhost:<em class="replaceable"><code>port_number</code></em>)</code></strong>
mysql-js&gt; <strong class="userinput"><code>dba.configureLocalInstance('root@localhost:<em class="replaceable"><code>port_number</code></em>)</code></strong>
 </pre><p>
          To check the cluster has been created, use the cluster
          instance's <code class="literal">status()</code> function. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#check-innodb-cluster-status" title="Checking the InnoDB Cluster Status">Checking the InnoDB Cluster Status</a>.
        </p><p>
          Once you have your cluster deployed you can configure MySQL Router
          to provide high availability, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-using-router" title="20.3 Using MySQL Router with InnoDB Cluster">Section 20.3, “Using MySQL Router with InnoDB Cluster”</a>.

          
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-production-deployment"></a>20.2.5 Production Deployment of InnoDB Cluster</h3>

</div>

</div>

</div>
<p>
        When working in a production environment, the MySQL server
        instances which make up an InnoDB cluster run on multiple host
        machines as part of a network

        

        rather than on single machine as described in
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-sandbox-deployment" title="20.2.4 Sandbox Deployment of InnoDB Cluster">Section 20.2.4, “Sandbox Deployment of InnoDB Cluster”</a>.
        Before proceeding with these instructions you must install the
        required software to each machine that you intend to add as a
        server instance to your cluster, see
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-methods-installing" title="20.2.3 Methods of Installing">Section 20.2.3, “Methods of Installing”</a>.
      </p><p>
        The following diagram illustrates the scenario you work with in
        this section:
</p>
<div class="figure">
<a name="production-servers-image"></a><p class="title"><b>Figure 20.2 Production Deployment</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/production_servers.png" width="600" height="837" alt="Three MySQL servers are grouped together as a production InnoDB cluster. One of the servers is the primary instance, and the other two are secondary instances. The IP address for the primary server is 139.59.177.10, and the IP addresses for the two secondary instances are 139.59.177.11 and 139.59.177.12. MySQL Router connects a client application to the primary instance. The admin capability in MySQL Shell interacts directly with the production InnoDB cluster.">
</div>

</div>

</div>
<br class="figure-break">
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          Unlike a sandbox deployment, where all instances are deployed
          locally to one machine, for a production deployment you must
          connect to each machine and run MySQL Shell locally before
          issuing <code class="literal">dba.configureLocalInstance()</code> on the
          instance. This ensures that any configuration changes are
          persisted into the option file on the instance. This also
          requires that you have access to the server and the required
          permissions to execute MySQL Shell.

          
</p>
</div>
<p>
        To pass a server's connection information to AdminAPI use
        URI type strings. See
        <a class="xref" href="mysql-shell.html#mysql-shell-connection-using-uri" title="18.2.1.1 Connecting using a URI String">Section 18.2.1.1, “Connecting using a URI String”</a> for more
        information.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="mysql-innodb-cluster-user-privileges"></a>User Privileges</h4>
</div>
</div>
</div>
<p>
          The user account used to administer an instance does not have
          to be the root account, however the user needs to be assigned
          full read and write privileges on the InnoDB cluster
          metadata tables in addition to full MySQL administrator
          privileges (<code class="literal">SUPER</code>, <code class="literal">GRANT
          OPTION</code>, <code class="literal">CREATE</code>,
          <code class="literal">DROP</code> and so on). To give the user
          <em class="replaceable"><code>your_user</code></em> the privileges needed to
          administer InnoDB cluster issue:
        </p><pre data-lang="sql" class="programlisting">
GRANT ALL PRIVILEGES ON mysql_innodb_cluster_metadata.* TO your_user@'%' WITH GRANT OPTION;
GRANT RELOAD, SHUTDOWN, PROCESS, FILE, SUPER, REPLICATION SLAVE, REPLICATION CLIENT, \
CREATE USER ON *.* TO your_user@'%' WITH GRANT OPTION;
GRANT SELECT ON *.* TO your_user@'%' WITH GRANT OPTION;
</pre><p>
          If only read operations are needed (such as for monitoring
          purposes), an account with more restricted privileges can be
          used. To give the user <em class="replaceable"><code>your_user</code></em>
          the privileges needed to monitor InnoDB cluster issue:
        </p><pre data-lang="sql" class="programlisting">
GRANT SELECT ON mysql_innodb_cluster_metadata.* TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.global_status TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_applier_configuration TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_applier_status TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_applier_status_by_coordinator TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_applier_status_by_worker TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_connection_configuration TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_connection_status TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_group_member_stats TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_group_members TO <em class="replaceable"><code>your_user@'%'</code></em>;
</pre><p>
          In this procedure the user <code class="literal">ic</code> is used in
          examples.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="mysql-innodb-cluster-production-hostname"></a>Configuring Hostname</h4>

</div>

</div>

</div>
<p>
          The production instances which make up a cluster run on
          separate machines, therefore each machine must have a unique
          host name and be able to resolve the host names of the other
          machines which run server instances in the cluster. If this is
          not the case, you can:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              configure each machine to map the IP of each other machine
              to a hostname. See your operating system documentation for
              details. This is the recommended solution.
            </p></li><li class="listitem"><p>
              set up a DNS service
            </p></li><li class="listitem"><p>
              configure the <a class="link" href="server-administration.html#sysvar_report_host"><code class="literal">report_host</code></a>
              variable in the MySQL configuration of each instance
</p></li></ul>
</div>
<p>
          In this procedure the host name
          <code class="literal">ic-<em class="replaceable"><code>number</code></em></code> is
          used in examples.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="mysql-innodb-cluster-logging"></a>Verbose Logging</h4>

</div>

</div>

</div>
<p>
          When working with a production deployment it can be useful to
          configure verbose logging for MySQL Shell, the information
          in the log can help you to find and resolve any issues that
          might occur when you are preparing server instances to work as
          part of InnoDB cluster. To start MySQL Shell with a
          verbose logging level use the
          <a class="link" href="programs.html#option_mysqlsh_log-level"><code class="option">--log-level</code></a> option:
        </p><pre data-lang="terminal" class="programlisting">
shell&gt; <strong class="userinput"><code>mysqlsh --log-level=DEBUG3</code></strong>
</pre><p>
          The <code class="literal">DEBUG3</code> is recommended, see
          <a class="link" href="programs.html#option_mysqlsh_log-level"><code class="option">--log-level</code></a> for more
          information. When <code class="literal">DEBUG3</code> is set the
          MySQL Shell log file contains lines such as <code class="literal">Debug:
          execute_sql( ... )</code> which contain the SQL queries
          that are executed as part of each AdminAPI call. The log file
          generated by MySQL Shell is located in
          <code class="filename">~/.mysqlsh/mysqlsh.log</code> for Unix-based
          systems; on Microsoft Windows systems it is located in
          <code class="filename">%APPDATA%\MySQL\mysqlsh\mysqlsh.log</code>. See
          <a class="xref" href="mysql-shell.html#mysql-shell-application-log" title="18.5 MySQL Shell Application Log">Section 18.5, “MySQL Shell Application Log”</a> for more
          information.
        </p><p>
          In addition to enabling the MySQL Shell log level, you can
          configure the amount of output AdminAPI provides in
          MySQL Shell after each call to the API. To enable the amount
          of AdminAPI output, in MySQL Shell issue:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; dba.verbose=2</pre><p>
          This enables the maximum output from AdminAPI calls. The
          available levels of output are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              0 or OFF is the default. This provides minimal output and
              is the recommended level when not troubleshooting.
            </p></li><li class="listitem"><p>
              1 or ON adds verbose output from each call to the
              AdminAPI.
            </p></li><li class="listitem"><p>
              2 adds debug output to the verbose output providing full
              information about what each call to AdminAPI executes.
</p></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="check-instance-configuration"></a>Checking Instance Configuration</h4>

</div>

</div>

</div>
<p>
          Before creating a production deployment from server instances
          you need to check that MySQL on each instance is correctly
          configured by using the
          <code class="literal">dba.checkInstanceConfiguration()</code> function.
          This ensures that the instance satisfies the
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-requirements" title="20.2.2 InnoDB Cluster Requirements">Section 20.2.2, “InnoDB Cluster Requirements”</a>. This does
          not check any data that is on the instance, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#check-instance-state" title="Checking Instance State">Checking Instance State</a> for more information.
          The following demonstrates issuing this in a running
          MySQL Shell:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>dba.checkInstanceConfiguration('ic@ic-1:3306')</code></strong>

Please provide the password for 'ic@ic-1:3306':
Validating instance...

The instance 'ic-1:3306' is not valid for Cluster usage.

The following issues were encountered:

- Some configuration options need to be fixed.

+----------------------------------+---------------+----------------+--------------------------------------------------+
| Variable                         | Current Value | Required Value | Note                                             |
+----------------------------------+---------------+----------------+--------------------------------------------------+
| binlog_checksum                  | CRC32         | NONE           | Update the server variable or restart the server |
| enforce_gtid_consistency         | OFF           | ON             | Restart the server                               |
| gtid_mode                        | OFF           | ON             | Restart the server                               |
| log_bin                          | 0             | 1              | Restart the server                               |
| log_slave_updates                | 0             | ON             | Restart the server                               |
| master_info_repository           | FILE          | TABLE          | Restart the server                               |
| relay_log_info_repository        | FILE          | TABLE          | Restart the server                               |
| transaction_write_set_extraction | OFF           | XXHASH64       | Restart the server                               |
+----------------------------------+---------------+----------------+--------------------------------------------------+


Please fix these issues , restart the server and try again.

{
  "config_errors": [
    {
      "action": "server_update",
      "current": "CRC32",
      "option": "binlog_checksum",
      "required": "NONE"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "enforce_gtid_consistency",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "gtid_mode",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "0",
      "option": "log_bin",
      "required": "1"
    },
    {
      "action": "restart",
      "current": "0",
      "option": "log_slave_updates",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "FILE",
      "option": "master_info_repository",
      "required": "TABLE"
    },
    {
      "action": "restart",
      "current": "FILE",
      "option": "relay_log_info_repository",
      "required": "TABLE"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "transaction_write_set_extraction",
      "required": "XXHASH64"
    }
  ],
  "errors": [],
  "restart_required": true,
  "status": "error"
}
mysql-js&gt;
</pre><p>
          Repeat this process for each server instance that you plan to
          use as part of your cluster. The reports generated after
          running <code class="literal">dba.checkInstanceConfiguration()</code>
          provide information about any configuration changes required
          before you can proceed. The
          <code class="literal">restart_required</code> field in the final part of
          the report tells you whether MySQL on the instance requires a
          restart to detect any change made to the configuration file.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="configuring-the-instance-id"></a>Configuring the Instance</h4>

</div>

</div>

</div>
<p>
          If configuration issues have been identified in the report
          generated by running
          <code class="literal">dba.checkInstanceConfiguration()</code> against
          the instance, it does not satisfy the
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-requirements" title="20.2.2 InnoDB Cluster Requirements">Section 20.2.2, “InnoDB Cluster Requirements”</a>. Therefore
          you need to connect to the machine and reconfigure the server
          instance. AdminAPI provides the
          <code class="literal">dba.configureLocalInstance()</code> function that
          finds the MySQL server's option file and modifies it to ensure
          that the instance is correctly configured for
          InnoDB cluster. Alternatively make the changes to the
          instance's option file manually based on the information
          in the report. See <a class="xref" href="programs.html#option-files" title="4.2.6 Using Option Files">Section 4.2.6, “Using Option Files”</a> for more
          information. Regardless of the way you make the configuration
          changes, you might have to restart MySQL to ensure the
          configuration changes are detected.

          
        </p><p>
          The recommended method is to log in to the remote machine, run
          MySQL Shell as the root user and then connect to the local
          MySQL server:
        </p><pre data-lang="terminal" class="programlisting">
shell&gt; <strong class="userinput"><code>sudo -i mysqlsh --log-level=DEBUG3</code></strong>
</pre><p>
          The <code class="literal">dba.configureLocalInstance()</code> method
          verifies that a suitable user is available for cluster usage,
          which is used for connections between members of the cluster.

          

          The root user cannot do remote logins by default, therefore
          you have three options to continue with the configuration:
          enable remote connections for the root user

          

          , create a new user or neither of these two previous options.
          The following example demonstrates the second option, creating
          a new user for cluster usage.

          

          The format of the user names accepted follows the standard
          MySQL account name format, see
          <a class="xref" href="security.html#account-names" title="6.2.3 Specifying Account Names">Section 6.2.3, “Specifying Account Names”</a>.
        </p><pre data-lang="mysqlsh" class="programlisting">
	
mysql-js&gt; <strong class="userinput"><code>dba.configureLocalInstance('root@localhost:3306')</code></strong>

Please provide the password for 'root@localhost:3306':

Please specify the path to the MySQL configuration file: /etc/mysql/mysql.conf.d/mysqld.cnf
Validating instance...

The configuration has been updated but it is required to restart the server.
{
  "config_errors": [
    {
      "action": "restart",
      "current": "OFF",
      "option": "enforce_gtid_consistency",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "gtid_mode",
      "required": "ON"
      },
    {
      "action": "restart",
      "current": "0",
      "option": "log_bin",
      "required": "1"
    },
    {
      "action": "restart",
      "current": "0",
      "option": "log_slave_updates",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "FILE",
      "option": "master_info_repository",
      "required": "TABLE"
    },
    {
      "action": "restart",
      "current": "FILE",
      "option": "relay_log_info_repository",
      "required": "TABLE"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "transaction_write_set_extraction",
      "required": "XXHASH64"
    }
  ],
  "errors": [],
  "restart_required": true,
  "status": "error"
}
mysql-js&gt;
</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            If the instance has
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
            might need to confirm that AdminAPI can set
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
            information.
</p>
</div>
<p>
          As with <code class="literal">dba.checkInstanceConfiguration()</code>,
          the configuration requirements are identified, but this time
          the chosen configuration file is modified. For the
          configuration changes to take effect you might need to restart
          the MySQL Server.
        </p><p>
          The <code class="literal">dba.configureLocalInstance()</code> function
          also accepts the <code class="literal">clusterAdmin</code> and
          <code class="literal">clusterAdminPassword</code> options, which enable
          you to configure the cluster user and password when calling
          the function. <code class="literal">clusterAdmin</code> supports
          identifiers or strings for the user name and host name. By
          default if unquoted it assumes input is a string. For example:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; dba.configureLocalInstance('ic@ic-1:3306', \ 
	      {clusterAdmin: 'icadmin@ic-1%',clusterAdminPassword: 'secret'});</pre><p>
          This user is granted the privileges for an administrative user
          described at
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-user-privileges" title="User Privileges">User Privileges</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="create-cluster"></a>Creating the Cluster</h4>

</div>

</div>

</div>
<p>
          Once you have prepared your instances, use the
          <code class="literal">dba.createCluster()</code> function to create the
          cluster. The machine which you are running MySQL Shell on is
          used as the seed instance for the cluster. The seed instance
          is replicated to the other instances which you add to the
          cluster, making them replicas of the seed instance.

          

          Log in to the instance and run MySQL Shell locally.
        </p><pre data-lang="terminal" class="programlisting">      
shell&gt; <strong class="userinput"><code>mysqlsh --uri ic@ic-1:3306</code></strong>

Creating a Session to 'ic@ic-1:3306'
Enter password: *********
Classic Session successfully established. No default schema selected.
</pre><p>
          MySQL Shell must be connected to an instance before you can
          create a cluster because when you issue
          <code class="literal">dba.createCluster(<em class="replaceable"><code>name</code></em>)</code>
          MySQL Shell creates a MySQL protocol session to the server
          instance connected to the MySQL Shell's current global
          session. Use the
          <code class="literal">dba.createCluster(<em class="replaceable"><code>name</code></em>)</code>
          function to create the cluster and assign the returned cluster
          to a variable called <code class="literal">cluster</code>:
        </p><pre data-lang="mysqlsh" class="programlisting">      
mysql-js&gt; <strong class="userinput"><code>var cluster = dba.createCluster('prodCluster')</code></strong>

      A new InnoDB cluster will be created on instance 'ic@ic-1:3306'.

      Creating InnoDB cluster 'prodCluster' on 'ic@ic-1:3306'...
      Adding Seed Instance...

      Cluster successfully created. Use Cluster.addInstance() to add MySQL instances.
      At least 3 instances are needed for the cluster to be able to withstand up to
      one server failure.
</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            If the instance has
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
            might need to confirm that AdminAPI can set
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
            information.
</p>
</div>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Note
</div>
<p>
            If you encounter an error related to metadata being
            inaccessible you might have the loopback network interface
            configured. For correct InnoDB cluster usage disable the
            loopback interface.
</p>
</div>
<p>
          To check the cluster has been created, use the cluster
          instance's <code class="literal">status()</code> function. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#check-innodb-cluster-status" title="Checking the InnoDB Cluster Status">Checking the InnoDB Cluster Status</a>.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            Once server instances belong to a cluster it is important to
            only administer them using MySQL Shell and AdminAPI.
            Attempting to manually change the configuration of Group
            Replication on an instance once it has been added to a
            cluster is not supported. Similarly, modifying server
            variables critical to InnoDB cluster, such as
            <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a> after an
            instance is configured using AdminAPI is not
            supported.
</p>
</div>
<p>
          Use the
          <code class="literal">cluster.addInstance(<em class="replaceable"><code>instance</code></em>)</code>
          function to add more instances to the cluster, where
          <em class="replaceable"><code>instance</code></em> is a URI type string to
          connect to the local instance. The instances must have been
          configured for cluster usage. You need a minimum of three
          instances in the cluster to make it tolerant to the failure of
          one instance. Adding further instances increases the tolerance
          to failure of an instance. To add an instance to the cluster
          issue:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>cluster.addInstance('ic@ic-2:3306');</code></strong>
</pre><p>
          To verify the instance has been added, use the cluster
          instance's <code class="literal">status()</code> function.

          
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
            At this stage, the server instances have been added to the
            cluster but the changes to the InnoDB cluster metadata
            have only been made on the instance which you are currently
            connected to. To make the configuration changes persistent
            for all instances in the cluster, you must connect to each
            instance and issue
            <code class="literal">dba.configureLocalInstance()</code> locally on
            each instance you have added. This is essential to ensure
            that instances rejoin the cluster in the event of leaving
            the cluster.
</p>
</div>
<p>
          To persist the InnoDB cluster metadata for all instances,
          log in to each instance that you added to the cluster and run
          MySQL Shell locally.
        </p><pre data-lang="terminal" class="programlisting">
shell&gt; <strong class="userinput"><code>mysqlsh</code></strong>
</pre><p>
          Use the <code class="literal">\connect</code> command to log in to MySQL
          server. Execute the
          <code class="literal">dba.configureLocalInstance('<em class="replaceable"><code>instance</code></em>')</code>
          function, where <em class="replaceable"><code>instance</code></em> is a URI
          type string to connect to the local instance. For example:
        </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; dba.configureLocalInstance('ic@ic-2:3306')
</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            If the instance has
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
            might need to confirm that AdminAPI can set
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
            information.
</p>
</div>
<p>
          Repeat this process for each server instance that you added to
          the cluster. Similarly if you modify the cluster structure,
          for example changing the number of instances, you need to
          repeat this process for each server instance to update the
          InnoDB cluster metadata accordingly for each instance in the
          cluster.
        </p><p>
          Once you have your cluster deployed you can configure MySQL Router
          to provide high availability, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-using-router" title="20.3 Using MySQL Router with InnoDB Cluster">Section 20.3, “Using MySQL Router with InnoDB Cluster”</a>.

          
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-from-group-replication"></a>20.2.6 Adopting a Group Replication Deployment</h3>

</div>

</div>

</div>
<p>
        If you have an existing deployment of Group Replication and you
        want to use it to create a cluster, pass the
        <code class="literal">adoptFromGR</code> option to the
        <code class="literal">dba.createCluster()</code> function. The created
        InnoDB cluster matches whether the replication group is
        running as single-primary or multi-primary.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
          Group Replication members might contain
          <a class="link" href="storage-engines.html#myisam-storage-engine" title="15.2 The MyISAM Storage Engine"><code class="literal">MyISAM</code></a> tables. Convert all such
          tables to <a class="link" href="innodb-storage-engine.html" title="Chapter 14 The InnoDB Storage Engine"><code class="literal">InnoDB</code></a> before adopting
          the group to an InnoDB cluster.

          
</p>
</div>
<p>
        To adopt an existing Group Replication group, connect to a group
        member using MySQL Shell. In the following example a
        single-primary group is adopted. We connect to
        <code class="literal">gr-member-2</code>, a secondary instance, while
        <code class="literal">gr-member-1</code> is functioning as the group's
        primary. Create a cluster using
        <code class="literal">dba.createCluster()</code>, passing in the
        <code class="literal">adoptFromGR</code> option. For example:
      </p><pre data-lang="mysqlsh" class="programlisting">  
mysql-js&gt; <strong class="userinput"><code>var cluster = dba.createCluster('prodCluster', {adoptFromGR: true});</code></strong>

A new InnoDB cluster will be created on instance 'root@gr-member-2:3306'.

Creating InnoDB cluster 'prodCluster' on 'root@gr-member-2:3306'...
Adding Seed Instance...

Cluster successfully created. Use cluster.addInstance() to add MySQL instances.
At least 3 instances are needed for the cluster to be able to withstand up to
one server failure.
</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
          If the instance has
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
          might need to confirm that AdminAPI can set
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
          information.
</p>
</div>
<p>
        The new cluster matches the mode of the group. If the adopted
        group was running in single-primary mode then a single-primary
        cluster is created. If the adopted group was running in
        multi-primary mode then a multi-primary cluster is created. For
        example:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>cluster.status();</code></strong>

{
    "clusterName": "prodCluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "gr-member-1:3306",
        "ssl": "REQUIRED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "gr-member-2:3306": {
                "address": "gr-member-2:3306",
                "mode": "R/O",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE"
            },
            "gr-member-1:3306": {
                "address": "gr-member-1:3306",
                "mode": "R/W",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE"
            },
            "gr-member-3:3306": {
                "address": "gr-member-3:3306",
                "mode": "R/O",
                "readReplicas": {},
                "role": "HA",
                "status": "ONLINE"
            }
        }
    }
}

	</pre><p>
        As seen above, the newly created cluster is single-primary and
        uses <code class="literal">gr-member-1</code> as the primary.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-using-router"></a>20.3 Using MySQL Router with InnoDB Cluster</h2>

</div>

</div>

</div>
<p>
      This section describes how to use MySQL Router with InnoDB cluster
      to achieve high availability. Regardless of whether you have
      deployed a sandbox or production cluster, MySQL Router can configure
      itself based on the InnoDB cluster's metadata using the
      <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option. This
      configures MySQL Router automatically to route connections to the
      cluster's server instances. Client applications connect to
      the ports MySQL Router provides, without any need to be aware of the
      InnoDB cluster topology. In the event of a unexpected failure,
      the InnoDB cluster adjusts itself automatically and MySQL Router
      detects the change. This removes the need for your client
      application to handle failover. For more information, see
      <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysql-router-innodb-cluster.html" target="_top">Routing for MySQL InnoDB cluster</a>.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
        Do not attempt to configure MySQL Router manually to redirect to the
        ports of an InnoDB cluster. Always use the
        <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option as this
        ensures that MySQL Router takes its configuration from the
        InnoDB cluster's metadata. See
        <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysql-router-general-metadata.html" target="_top">Cluster Metadata and State</a>.
</p>
</div>
<p>
      The recommended deployment of MySQL Router is on the same host as the
      application. When using a sandbox deployment, everything is
      running on a single host, therefore you deploy MySQL Router to the
      same host. When using a production deployment, we recommend
      deploying one MySQL Router instance to each machine used to host one
      of your client applications. It is also possible to deploy
      MySQL Router to a common machine through which your application
      instances connect. You need the MASTER key of the InnoDB cluster
      to auto-configure MySQL Router.

      
    </p><p>
      Assuming MySQL Router is already installed (see
      <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysql-router-installation.html" target="_top">Installing MySQL Router</a>), use the
      <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option to provide
      the location of a server instance that belongs to the
      InnoDB cluster. MySQL Router uses the included metadata cache

      

      plugin to retrieve the InnoDB cluster's metadata,
      consisting of a list of server instance addresses which make up
      the InnoDB cluster and their role in the cluster. You pass the
      URI type string of the server that MySQL Router should retrieve the
      InnoDB cluster metadata from. For example:
    </p><pre data-lang="terminal" class="programlisting">
shell&gt; <strong class="userinput"><code>mysqlrouter --bootstrap ic@ic-1:3306 --user=mysqlrouter </code></strong>
</pre><p>
      You are prompted for the instance password and encryption key for
      MySQL Router to use. This encryption key is used to encrypt the
      instance password used by MySQL Router to connect to the cluster. The
      ports you can use to connect to the InnoDB cluster are also
      displayed. The MySQL Router bootstrap process creates a
      <code class="filename">mysqlrouter.conf</code> file, with the settings
      based on the cluster metadata retrieved from the address passed to
      the <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option, in the
      above example <code class="literal">ic@ic-1:3306</code>. Based on the
      InnoDB cluster metadata retrieved, MySQL Router automatically
      creates a configuration file, including a
      <code class="literal">metadata_cache</code> section with
      <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysql-router-conf-options.html#option_mysqlrouter_bootstrap_server_addresses" target="_top"><code class="option">bootstrap_server_addresses</code></a>
      containing the addresses for all server instances in the cluster.
      For example:
    </p><pre data-lang="ini" class="programlisting">
[metadata_cache:prodCluster]
router_id=1
bootstrap_server_addresses=mysql://ic@ic-1:3306,mysql://ic@ic-2:3306,mysql://ic@ic-3:3306
user=mysql_router1_jy95yozko3k2
metadata_cluster=prodCluster
ttl=300
</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
        When you change the topology of a cluster by adding another
        server instance after you have bootstrapped MySQL Router, you need
        to update
        <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysql-router-conf-options.html#option_mysqlrouter_bootstrap_server_addresses" target="_top"><code class="option">bootstrap_server_addresses</code></a>
        based on the updated metadata. Either restart MySQL Router using the
        <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option, or
        manually edit the
        <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysql-router-conf-options.html#option_mysqlrouter_bootstrap_server_addresses" target="_top"><code class="option">bootstrap_server_addresses</code></a>
        section of the <code class="filename">mysqlrouter.conf</code> file and
        restart MySQL Router.
</p>
</div>
<p>
      The generated MySQL Router configuration creates TCP ports which you
      use to connect to the cluster. Ports for communicating with the
      cluster using both Classic MySQL protocol and X Protocol are
      created. To use X Protocol the server instances must have
      X Plugin installed and configured. For a sandbox deployment,
      instances have X Plugin set up automatically. For a
      production deployment, if you want to use X Protocol you
      need to install and configure X Plugin on each instance, see
      <a class="xref" href="document-store.html#document-store-setting-up" title="19.3 Setting Up MySQL as a Document Store">Section 19.3, “Setting Up MySQL as a Document Store”</a>. The default available
      TCP ports are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          <code class="literal">6446</code> - for Classic MySQL protocol
          read-write sessions, which MySQL Router redirects incoming
          connections to primary server instances.
        </p></li><li class="listitem"><p>
          <code class="literal">6447</code> - for Classic MySQL protocol read-only
          sessions, which MySQL Router redirects incoming connections to one
          of the secondary server instances.
        </p></li><li class="listitem"><p>
          <code class="literal">64460</code> - for X Protocol read-write
          sessions, which MySQL Router redirects incoming connections to
          primary server instances.
        </p></li><li class="listitem"><p>
          <code class="literal">64470</code> - for X Protocol read-only
          sessions, which MySQL Router redirects incoming connections to one
          of the secondary server instances.
</p></li></ul>
</div>
<p>
      Depending on your MySQL Router configuration the port numbers might be
      different to the above. For example if you use the
      <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysqlrouter.html#option_mysqlrouter_conf-base-port" target="_top"><code class="option">--conf-base-port</code></a> option, or
      the
      <a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode</code></a>
      variable. The exact ports are listed when you start MySQL Router.
    </p><p>
      The way incoming connections are redirected depends on the type of
      cluster being used. When using a single-primary cluster,
      read-write sessions are redirected to the single primary, with a
      multi-primary cluster read-write sessions are redirected to one of
      the primary instances.

      

      For incoming read-only connections MySQL Router redirects connections
      to one of the secondary instances in a round-robin fashion.

      
    </p><p>
      Once bootstrapped and configured, start MySQL Router:
    </p><pre data-lang="terminal" class="programlisting">
shell&gt; <strong class="userinput"><code>mysqlrouter &amp;</code></strong>
</pre><p>
      Alternatively set up a service to start MySQL Router automatically
      when the system boots, see
      <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysql-router-server-starting.html" target="_top">Starting MySQL Router</a>. You can now
      connect a MySQL client, such as MySQL Shell to one of the
      incoming MySQL Router ports as described above and see how the client
      gets transparently connected to one of the InnoDB cluster
      instances.
    </p><pre data-lang="terminal" class="programlisting">
shell&gt; <strong class="userinput"><code>mysqlsh --uri root@localhost:6442</code></strong>
</pre><p>
      To verify which instance you are actually connected to, simply
      issue an SQL query against the
      <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a> status variable.

      
    </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>\sql</code></strong>
Switching to SQL mode... Commands end with ;
mysql-sql&gt; <strong class="userinput"><code>select @@port;</code></strong>
+--------+
| @@port |
+--------+
|   3310 |
+--------+
</pre>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h3 class="title"><a name="test-failover"></a>Testing High Availability</h3>
</div>
</div>
</div>
<p>
        To test if high availability works, simulate an unexpected halt
        by killing an instance. The cluster detects the fact that the
        instance left the cluster and reconfigures itself. Exactly how
        the cluster reconfigures itself depends on whether you are using
        a single-primary or multi-primary cluster, and the role the
        instance serves within the cluster.
      </p><p>
        In single-primary mode:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            If the current primary leaves the cluster, one of the
            secondary instances is elected as the new primary, with
            instances prioritized by the lowest
            <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a>. MySQL Router
            redirects read-write connections to the newly elected
            primary.
          </p></li><li class="listitem"><p>
            If a current secondary leaves the cluster, MySQL Router stops
            redirecting read-only connections to the instance.
</p></li></ul>
</div>
<p>
        For more information see
        <a class="xref" href="group-replication.html#group-replication-single-primary-mode" title="17.4.1.1 Single-Primary Mode">Section 17.4.1.1, “Single-Primary Mode”</a>.
      </p><p>
        In multi-primary mode:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            If a current "R/W" instance leaves the cluster, MySQL Router
            redirects read-write connections to other primaries.

            
          </p></li><li class="listitem"><p>
            If a current "R/O" instance leaves the cluster,

            
</p></li></ul>
</div>
<p>
        For more information see
        <a class="xref" href="group-replication.html#group-replication-multi-primary-mode" title="17.4.1.2 Multi-Primary Mode">Section 17.4.1.2, “Multi-Primary Mode”</a>.
      </p><p>
        There are various ways to simulate an instance leaving a
        cluster, for example you can forcibly stop the MySQL server on
        an instance, or use the AdminAPI
        <code class="literal">dba.killSandboxInstance()</code> if testing a
        sandbox deployment. In this example assume there is a
        single-primary sandbox cluster deployment with three server
        instances and the instance listening at port 3310 is the current
        primary. Simulate the instance leaving the cluster unexpectedly:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>dba.killSandboxInstance(3310)</code></strong>
</pre><p>
        Switch to SQL mode in MySQL Shell using the
        <code class="literal">\sql</code> command and verify the
        <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a> variable to check which
        instance you are connected to.

        

        Notice that the first <a class="link" href="sql-syntax.html#select" title="13.2.9 SELECT Syntax"><code class="literal">SELECT</code></a>
        statement fails as the connection to the original primary was
        lost. This means the current session has been closed,
        MySQL Shell automatically reconnects for you and when you
        issue the command again the new port is confirmed.
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>\sql</code></strong>
Switching to SQL mode... Commands end with ;
mysql-sql&gt; <strong class="userinput"><code>SELECT @@port;</code></strong>
ERROR: 2013 (HY000): Lost connection to MySQL server during query
The global session got disconnected.
Attempting to reconnect to 'root@localhost:6446'...
The global session was successfully reconnected.
mysql-sql&gt; <strong class="userinput"><code>SELECT @@port;</code></strong>
+--------+
| @@port |
+--------+
|   3330 |
+--------+
1 row in set (0.00 sec)
</pre><p>
        This shows that the InnoDB cluster provided us with automatic
        failover, that MySQL Router has automatically reconnected us to the
        new primary instance, and that we have high availability.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="router-and-metadata-servers"></a>MySQL Router and Metadata Servers</h3>

</div>

</div>

</div>
<p>
        When MySQL Router is bootstrapped against a cluster, it records the
        server instance's addresses in its configuration file. If
        any additional instances are added to the cluster after
        bootstrapping the MySQL Router, they are not automatically detected
        and therefore are <span class="emphasis"><em>not</em></span> used for connection
        routing.
      </p><p>
        To ensure that newly added instances are routed to correctly you
        must bootstrap MySQL Router against the cluster to read the updated
        metadata. This means that you must restart MySQL Router and include
        the <a class="ulink" href="http://dev.mysql.com/doc/mysql-router/2.1/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-working-with-cluster"></a>20.4 Working with InnoDB Cluster</h2>

</div>

</div>

</div>
<p>
      This section explains how to work with InnoDB cluster, and how
      to handle common administration tasks.

      
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#retrieving-an-innodb-cluster" title="Retrieving an InnoDB cluster">Retrieving an InnoDB cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#check-innodb-cluster-status" title="Checking the InnoDB Cluster Status">Checking the InnoDB Cluster Status</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#describe-structure-innodb-cluster" title="Describing the Structure of the InnoDB Cluster">Describing the Structure of the InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#manage-sandbox-instances" title="Managing Sandbox Instances">Managing Sandbox Instances</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#remove-instances-from-innodb-cluster" title="Removing Instances from the InnoDB Cluster">Removing Instances from the InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#customize-your-cluster" title="Customizing InnoDB clusters">Customizing InnoDB clusters</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#rejoin-cluster" title="Rejoining a Cluster">Rejoining a Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#restore-cluster-from-quorum-loss" title="Restoring a Cluster from Quorum Loss">Restoring a Cluster from Quorum Loss</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#reboot-outage" title="Rebooting a Cluster from a Major Outage">Rebooting a Cluster from a Major Outage</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#rescan-cluster" title="Rescanning a Cluster">Rescanning a Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#check-instance-state" title="Checking Instance State">Checking Instance State</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#dissolve-innodb-cluster" title="Dissolving an InnoDB Cluster">Dissolving an InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-securing" title="Securing your Cluster">Securing your Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#create-whitelist-servers" title="Creating a Whitelist of Servers">Creating a Whitelist of Servers</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#use-mysql-shell-execute-script" title="Using MySQL Shell to Execute a Script">Using MySQL Shell to Execute a Script</a></p></li></ul>
</div>

<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h3 class="title"><a name="retrieving-an-innodb-cluster"></a>Retrieving an InnoDB cluster</h3>

</div>

</div>

</div>
<p>
        When you create a cluster using
        <code class="literal">dba.createCluster()</code>, the operation returns a
        Cluster object which can be assigned to a variable. You use this
        object to work with the cluster, for example to add instances or
        check the cluster's status. If you want to retrieve a cluster
        again at a later date, for example after restarting
        MySQL Shell, use the
        <code class="literal">dba.getCluster(<em class="replaceable"><code>name</code></em>,
        [<em class="replaceable"><code>options</code></em>])</code> function. For
        example:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>var cluster1 = dba.getCluster()</code></strong>
</pre><p>
        If you do not specify a cluster <em class="replaceable"><code>name</code></em>
        then the default cluster is returned. If there is more than one
        cluster stored in the InnoDB cluster metadata of the server
        instance which the MySQL Shell global session is currently
        connected to, specify the <em class="replaceable"><code>name</code></em> of the
        cluster you want to retrieve.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="check-innodb-cluster-status"></a>Checking the InnoDB Cluster Status</h3>

</div>

</div>

</div>
<p>
        Cluster objects provide the <code class="literal">status()</code> method
        that enables you to check how a cluster is running. Before you
        can check the status of the InnoDB cluster, you need to get a
        reference to the InnoDB cluster object by connecting to any of
        its instances. However, if you want to make changes to the
        configuration of the cluster, you must connect to a "R/W"
        instance. Issuing <code class="literal">status()</code> retrieves the
        status of the cluster based on the view of the cluster which the
        server instance you are connected to is aware of and outputs a
        status report.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          The instance's state in the cluster directly influences the
          information provided in the status report. An instance which
          has left the cluster provides a different view of the cluster
          compared to a instance which belongs to the cluster. Therefore
          ensure the instance you are connected to has a status of
          <code class="literal">ONLINE</code>.

          
</p>
</div>
<p>
        For information about how the InnoDB cluster is running, use
        the cluster's <code class="literal">status()</code> method:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>var cluster = dba.getCluster()</code></strong>
mysql-js&gt; <strong class="userinput"><code>cluster.status()</code></strong>
{
    "clusterName": "testCluster", 
    "defaultReplicaSet": {
        "name": "default", 
        "primary": "localhost:3320", 
	"ssl": "REQUIRED",
        "status": "OK", 
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", 
        "topology": {
            "localhost:3310": {
                "address": "localhost:3310", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }, 
            "localhost:3320": {
                "address": "localhost:3320", 
                "mode": "R/W", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }, 
            "localhost:3330": {
                "address": "localhost:3330", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }
        }
    }
}
</pre><p>
        The information output by <code class="literal">cluster.status()</code>
        provides the following information:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            clusterName: name assigned to this cluster during
            <code class="literal">dba.createCluster()</code>.
          </p></li><li class="listitem"><p>
            defaultReplicaSet: the server instances which belong to an
            InnoDB cluster and contain the data set.
          </p></li><li class="listitem"><p>
            primary: displayed when the cluster is operating in
            single-primary mode only. Shows the address of the current
            primary instance. If this field is not displayed, the
            cluster is operating in multi-primary mode.
          </p></li><li class="listitem"><p>
            ssl: whether secure connections are used by the cluster or
            not. Shows values of <code class="literal">REQUIRED</code> or
            <code class="literal">DISABLED</code>, depending on how the
            <code class="literal">memberSslMode</code> option was configured
            during either <code class="literal">createCluster()</code> or
            <code class="literal">addInstance()</code>. The value returned by this
            parameter corresponds to the value of the
            <a class="link" href="group-replication.html#sysvar_group_replication_ssl_mode"><code class="literal">group_replication_ssl_mode</code></a>
            server variable on the instance. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-securing" title="Securing your Cluster">Securing your Cluster</a>.
          </p></li><li class="listitem"><p>
            status: The status of this element of the cluster. For the
            overall cluster this describes the high availability
            provided by this cluster. The status is one of the
            following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                <code class="literal">ONLINE</code>: The instance is online and
                participating in the cluster.
              </p></li><li class="listitem"><p>
                <code class="literal">OFFLINE</code>: The instance has lost
                connection to the other instances.
              </p></li><li class="listitem"><p>
                <code class="literal">RECOVERING</code>: The instance is
                attempting to synchronize with the cluster by retrieving
                transactions it needs before it can become an
                <code class="literal">ONLINE</code> member.
              </p></li><li class="listitem"><p>
                <code class="literal">UNREACHABLE</code>: The instance has lost
                communication with the cluster.
              </p></li><li class="listitem"><p>
                <code class="literal">ERROR</code>: The instance has encountered
                an error during the recovery phase or while applying a
                transaction.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
                  Once an instance enters <code class="literal">ERROR</code>
                  state, the
                  <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a>
                  option is set to <code class="literal">ON</code>. To leave the
                  <code class="literal">ERROR</code> state you must manually
                  configure the instance with
                  <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>.
</p>
</div>
</li><li class="listitem"><p>
                <code class="literal">(MISSING)</code>: The state of an instance
                which is part of the configured cluster, but is
                currently unavailable.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
                  The <code class="literal">MISSING</code> state is specific to
                  InnoDB cluster, it is not a state generated by Group
                  Replication. MySQL Shell uses this state to indicate
                  instances that are registered in the metadata, but
                  cannot be found in the live cluster view.
</p>
</div>
</li></ul>
</div>
</li><li class="listitem"><p>
            topology: The instances which have been added to the
            cluster.
          </p></li><li class="listitem"><p>
            Host name of instance: The host name of an instance, for
            example localhost:3310.
          </p></li><li class="listitem"><p>
            role: what function this instance provides in the cluster.
            Currently only HA, for high availability.
          </p></li><li class="listitem"><p>
            mode: whether the server is read-write ("R/W") or read-only
            ("R/O"). The mode indicates either <code class="literal">R/W</code>
            (read and writable) or <code class="literal">R/O</code> (read only).
            In single-primary mode, only the one instance marked "R/W"
            can execute transactions that update the database, so it is
            the primary. If that instance becomes unreachable for any
            reason (like an unexpected halt), one of the remaining "R/O"
            instances automatically takes over its place and becomes the
            new "R/W" primary. In multi-primary mode, all instances are
            marked as "R/W" and there is no single elected primary.
</p></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="describe-structure-innodb-cluster"></a>Describing the Structure of the InnoDB Cluster</h3>

</div>

</div>

</div>
<p>
        To get information about the structure of the InnoDB cluster
        itself, use the <code class="literal">cluster.describe()</code> function:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>cluster.describe();</code></strong>
{
    "clusterName": "test",
    "adminType": "local",
    "defaultReplicaSet": {
        "name": "default",
        "instances": [
            {
                "name": "localhost:3310",
                "host": "localhost:3310",
                "role": "HA"
            },
            {
                "name": "localhost:3320",
                "host": "localhost:3320",
                "role": "HA"
            },
            {
                "name": "localhost:3330",
                "host": "localhost:3330",
                "role": "HA"
            }
        ]
    }
}
</pre><p>
        The output from this function shows the structure of the
        InnoDB cluster including all of its configuration information,
        and so on.

        
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="super-read-only-on-instance"></a>Super Read-only and Instances</h3>

</div>

</div>

</div>
<p>
        Whenever Group Replication stops, the
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> variable is set
        to <code class="literal">ON</code> to ensure no writes are made to the
        instance. When you try to use such an instance with the
        following AdminAPI commands you are given the choice to set
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a> on the
        instance:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">dba.configureLocalInstance()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">dba.createCluster()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">dba.rebootClusterFromCompleteOutage()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">dba.dropMetadataSchema()</code>
</p></li></ul>
</div>
<p>
        When AdminAPI encounters an instance which has
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a>, in
        interactive mode you are given the choice to set
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. For
        example:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; var myCluster = dba.createCluster('testCluster')
A new InnoDB cluster will be created on instance 'ic@ic-1:3306'.

The MySQL instance at 'ic@ic-1:3306' currently has the super_read_only 
system variable set to protect it from inadvertent updates from applications. 
You must first unset it to be able to perform any changes to this instance. 
For more information see: https://dev.mysql.com/doc/refman/en/server-system-variables.html#sysvar_super_read_only.

Note: there are open sessions to 'ic@ic-1:3306'.
You may want to kill these sessions to prevent them from performing unexpected updates: 

1 open session(s) of 'ic@ic-1:3306'. 


Do you want to disable super_read_only and continue? [y|N]: 
	</pre><p>
        The number of current active sessions to the instance is shown.
        You must ensure that no applications might write to the instance
        inadvertently. By answering <code class="literal">y</code> you confirm
        that AdminAPI can write to the instance. If there is more than
        one open session to the instance listed, exercise caution before
        permitting AdminAPI to set
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>.
      </p><p>
        To force the function to set
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a> in a
        script, pass the <code class="literal">clearReadOnly</code> option set to
        <code class="literal">true</code>. For example
        <code class="literal">dba.configureLocalInstance(instance, {clearReadOnly:
        true}).</code>
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="manage-sandbox-instances"></a>Managing Sandbox Instances</h3>

</div>

</div>

</div>
<p>
        Once a sandbox instance is running, it is possible to change its
        status at any time using the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            To stop a sandbox instance use
            <code class="literal">dba.stopSandboxInstance(<em class="replaceable"><code>instance</code></em>)</code>.
            This stops the instance gracefully, unlike
            <code class="literal">dba.killSandboxInstance(<em class="replaceable"><code>instance</code></em>)</code>.
          </p></li><li class="listitem"><p>
            To start a sandbox instance use
            <code class="literal">dba.startSandboxInstance(<em class="replaceable"><code>instance</code></em>)</code>.
          </p></li><li class="listitem"><p>
            To kill a sandbox instance use
            <code class="literal">dba.killSandboxInstance(<em class="replaceable"><code>instance</code></em>)</code>.
            This stops the instance without gracefully stopping it and
            is useful in simulating unexpected halts.
          </p></li><li class="listitem"><p>
            To delete a sandbox instance use
            <code class="literal">dba.deleteSandboxInstance(<em class="replaceable"><code>instance</code></em>)</code>.
            This completely removes the sandbox instance from your file
            system.
</p></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="remove-instances-from-innodb-cluster"></a>Removing Instances from the InnoDB Cluster</h3>

</div>

</div>

</div>
<p>
        You can remove an instance from a cluster at any time should you
        wish to do so. This can be done with the
        <code class="literal">removeInstance()</code> method, as in the following
        example:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>cluster.removeInstance('root@localhost:3310')</code></strong>
</pre>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="customize-your-cluster"></a>Customizing InnoDB clusters</h3>

</div>

</div>

</div>
<p>
        When you create a cluster and add instances to it, values such
        as the group name, the local address, and the seed instances are
        configured automatically by AdminAPI. These default
        values are recommended for most deployments, but advanced users
        can override these defaults by passing the following options to
        the <code class="literal">dba.createCluster()</code> and
        <code class="literal">cluster.addInstance()</code>.
      </p><p>
        To customize the name of the replication group created by
        InnoDB cluster, pass the <code class="literal">groupName</code> option
        to the <code class="literal">dba.createCluster()</code> command. This sets
        the
        <a class="link" href="group-replication.html#sysvar_group_replication_group_name"><code class="literal">group_replication_group_name</code></a>
        system variable. The name must be a valid UUID.
      </p><p>
        To customize the address which an instance provides for
        connections from other instances, pass the
        <code class="literal">localAddress</code> option to the
        <code class="literal">dba.createCluster()</code> and
        <code class="literal">cluster.addInstance()</code> commands. Specify the
        address in the format
        <code class="literal"><em class="replaceable"><code>host</code></em>:<em class="replaceable"><code>port</code></em></code>.
        This sets the
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
        system variable on the instance. The address must be accessible
        to all instances in the cluster, and must be reserved for
        internal cluster communication only. In other words do not use
        this address for communication with the instance.
      </p><p>
        To customize the instances used as seeds when an instance joins
        the cluster, pass the <code class="literal">groupSeeds</code> option to
        the <code class="literal">dba.createCluster()</code> and
        <code class="literal">cluster.addInstance()</code> commands. Seed
        instances are contacted when a new instance joins a cluster and
        used to provide data to the new instance. The addresses are
        specified as a comma separated list such as
        <code class="literal">host1:port1</code>,<code class="literal">host2:port2</code>.
        This configures the
        <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
        system variable.
      </p><p>
        For more information see the documentation of the system
        variables configured by these AdminAPI options.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="rejoin-cluster"></a>Rejoining a Cluster</h3>

</div>

</div>

</div>
<p>
        If an instance leaves the cluster, for example because it lost
        connection and did not or could not automatically rejoin the
        cluster, it might be necessary to rejoin it to the cluster at a
        later stage. To rejoin an instance to a cluster issue
        <code class="literal">cluster.rejoinInstance()</code>.
      </p><p>
        In the case where an instance has not had it's
        configuration persisted, for example when you have not issued
        <code class="literal">dba.configureLocalInstance()</code>
        <span class="emphasis"><em>locally</em></span> on the instance but it has been
        added to a cluster, upon restart the instance does not rejoin
        the cluster automatically. The solution is to issue
        <code class="literal">cluster.rejoinInstance()</code> so that the instance
        is added to the cluster again. Then connect to the instance, run
        MySQL Shell locally and issue
        <code class="literal">dba.configureLocalInstance()</code>. This ensures
        the InnoDB cluster configuration is persisted to the
        instance's option file to enable it to rejoin the cluster
        automatically.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
          If the instance has
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
          might need to confirm that AdminAPI can set
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
          information.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="restore-cluster-from-quorum-loss"></a>Restoring a Cluster from Quorum Loss</h3>

</div>

</div>

</div>
<p>
        If a instance (or instances) fail, then a cluster can lose its
        quorum, which is the ability to vote in a new primary. In this
        case you can re-establish quorum using the method
        <code class="literal">cluster.forceQuorumUsingPartitionOf()</code>, as
        shown in the following MySQL Shell example:
      </p><pre data-lang="mysqlsh" class="programlisting">
  // open session to a cluster

mysql-js&gt; <strong class="userinput"><code>cluster = dba.getCluster("prodCluster")</code></strong>

  // The cluster lost its quorum and its status shows
  // "status": "NO_QUORUM"

mysql-js&gt; <strong class="userinput"><code>cluster.forceQuorumUsingPartitionOf("localhost:3310")</code></strong>

  Restoring replicaset 'default' from loss of quorum, by using the partition composed of [localhost:3310]

  Please provide the password for 'root@localhost:3310': ******
  Restoring the InnoDB cluster ...

  The InnoDB cluster was successfully restored using the partition from the instance 'root@localhost:3310'.

  WARNING: To avoid a split-brain scenario, ensure that all other members of the replicaset
  are removed or joined back to the group that was restored.
</pre>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="reboot-outage"></a>Rebooting a Cluster from a Major Outage</h3>

</div>

</div>

</div>
<p>
        

        If your cluster suffers from a complete outage, you can ensure
        it is reconfigured correctly using
        <code class="literal">dba.rebootClusterFromCompleteOutage()</code>. In the
        event that a cluster has completely stopped, the instances must
        be started and only then can the cluster be started. For example
        if the machine a sandbox cluster was running on has been
        restarted, and the instances were at ports 3310, 3320 and 3330,
        issue:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; dba.startSandboxInstance(3310)
mysql-js&gt; dba.startSandboxInstance(3320)
mysql-js&gt; dba.startSandboxInstance(3330)
    </pre><p>
        This ensures the sandbox instances are running. In the case of a
        production deployment you would have to start the instances
        outside of MySQL Shell. Once the instances have started,
        connect to an instance and run MySQL Shell. Then restart the
        cluster by issuing:
      </p><pre data-lang="mysqlsh" class="programlisting">
<strong class="userinput"><code>        
mysql-js&gt; <strong class="userinput"><code>shell.connect('root@localhost:3310');</code></strong>
mysql-js&gt; <strong class="userinput"><code>var cluster = dba.rebootClusterFromCompleteOutage();</code></strong>
</code></strong>
</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
          If the instance has
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
          might need to confirm that AdminAPI can set
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
          information.
</p>
</div>
<p>
        This ensures the cluster is correctly reconfigured after a
        complete outage. It uses the instance that MySQL Shell is
        connected to as the new seed instance and recovers the cluster
        based on the existing metadata of that instance.
      </p><p>
        If this process fails, and the cluster metadata has become badly
        corrupted, you might need to drop the metadata and create the
        cluster again from scratch. You can drop the cluster metadata
        using <code class="literal">dba.dropMetadataSchema()</code>.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          The <code class="literal">dba.dropMetadataSchema()</code> method should
          only be used as a last resort, when it is not possible to
          restore the cluster. It cannot be undone.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="rescan-cluster"></a>Rescanning a Cluster</h3>

</div>

</div>

</div>
<p>
        If changes to an instance's configuration are made without
        using AdminAPI, you need to rescan the cluster to update the
        InnoDB cluster metadata. For example, if you manually add a
        new instance to the Group Replication group, the
        InnoDB cluster metadata is not modified based on this change
        to the cluster because MySQL Shell was not used. In such a
        scenario it is necessary to rescan the cluster with
        <code class="literal">cluster.rescan()</code> to update the
        InnoDB cluster metadata.
      </p><p>
        After the command <code class="literal">cluster.rescan()</code> has been
        run, instances are identified that are newly discovered
        instances. You are prompted to add each of these newly
        discovered instances into your cluster as required, or you can
        choose to ignore them.
      </p><p>
        Instances that no longer belong to the cluster or which are
        unavailable are also reported. In this case you are prompted to
        remove the instance, or you can later attempt to add it back
        into the cluster using a command such as
        <code class="literal">cluster.rejoin('ic@ic-4:3306')</code>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="check-instance-state"></a>Checking Instance State</h3>

</div>

</div>

</div>
<p>
        The <code class="literal">cluster.checkInstanceState()</code> function can
        be used to to verify the existing data on an instance does not
        prevent it from joining a cluster. This process works by
        validating the instance's global transaction identifier (GTID)
        state compared to the GTIDs already processed by the cluster.
        For more information on GTIDs see
        <a class="xref" href="replication.html#replication-gtids-concepts" title="16.1.3.1 GTID Format and Storage">Section 16.1.3.1, “GTID Format and Storage”</a>. This check enables
        you to determine if an instance which has processed transactions
        can be added to the cluster.
      </p><p>
        The following demonstrates issuing this in a running
        MySQL Shell:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>cluster.checkInstanceState('ic@ic-4:3306')</code></strong>
</pre><p>
        

        The output of this function can be one of the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            OK new: the instance has not executed any GTID transactions,
            therefore it cannot conflict with the GTIDs executed by the
            cluster
          </p></li><li class="listitem"><p>
            OK recoverable: the instance has executed GTIDs which do not
            conflict with the executed GTIDs of the cluster seed
            instances
          </p></li><li class="listitem"><p>
            ERROR diverged: the instance has executed GTIDs which
            diverge with the executed GTIDs of the cluster seed
            instances
          </p></li><li class="listitem"><p>
            ERROR lost_transactions: the instance has more executed
            GTIDs than the executed GTIDs of the cluster seed instances
</p></li></ul>
</div>
<p>
        Instances with an OK status can be added to the cluster because
        any data on the instance is consistent with the cluster. In
        other words the instance being checked has not executed any
        transactions which conflict with the GTIDs executed by the
        cluster, and can be recovered to the same state as the rest of
        the cluster instances.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="dissolve-innodb-cluster"></a>Dissolving an InnoDB Cluster</h3>

</div>

</div>

</div>
<p>
        To dissolve an InnoDB cluster you connect to a read-write
        instance, for example the primary in a single-primary cluster,
        and use the <code class="literal">Cluster.dissolve()</code> command. This
        removes all metadata and configuration associated with the
        cluster, and disables Group Replication on the instances. Any
        data that was replicated between the instances is not removed.
        There is no way to undo the dissolving of a cluster, therefore
        you must pass <code class="literal">force: true</code> to confirm you want
        to dissolve the cluster. For example: to create it again use
        <code class="literal">dba.createCluster()</code>.
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt; <strong class="userinput"><code>session</code></strong>
&lt;ClassicSession:root@localhost:3310&gt;
mysql-js&gt; <strong class="userinput"><code>cluster.dissolve({force:true})</code></strong>
The cluster was successfully dissolved.
Replication was disabled but user data was left intact.
</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
          After issuing <code class="literal">cluster.dissolve()</code>, any
          variable assigned to the <code class="literal">Cluster</code> object is
          no longer valid.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="mysql-innodb-cluster-securing"></a>Securing your Cluster</h3>

</div>

</div>

</div>
<p>
        Server instances can be configured to use secure connections.
        For general information on using SSL with MySQL see
        <a class="xref" href="security.html#encrypted-connections" title="6.4 Using Encrypted Connections">Section 6.4, “Using Encrypted Connections”</a>. This section explains
        how to configure a cluster to use SSL. An additional security
        possibility is to configure which servers can access the
        cluster, see <a class="xref" href="mysql-innodb-cluster-userguide.html#create-whitelist-servers" title="Creating a Whitelist of Servers">Creating a Whitelist of Servers</a>.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          Once you have configured a cluster to use SSL you must add the
          servers to the <code class="literal">ipWhitelist</code>.
</p>
</div>
<p>
        When using <code class="literal">dba.createCluster()</code> to set up a
        cluster, if the server instance provides SSL encryption then it
        is automatically enabled on the seed instance. Pass the
        <code class="literal">memberSslMode</code> option to the
        <code class="literal">dba.createCluster()</code> method to specify a
        different SSL mode. The SSL mode of a cluster can only be set at
        the time of creation. The <code class="literal">memberSslMode</code>
        option is a string that configures the SSL mode to be used, it
        defaults to <code class="literal">AUTO</code>. The permitted values are
        <code class="literal">DISABLED</code>, <code class="literal">REQUIRED</code>, and
        <code class="literal">AUTO</code>. These modes are defined as:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Setting
            <code class="literal">createCluster({memberSslMode:'DISABLED'})</code>
            ensures SSL encryption is disabled for the seed instance in
            the cluster.
          </p></li><li class="listitem"><p>
            Setting
            <code class="literal">createCluster({memberSslMode:'REQUIRED'})</code>
            then SSL encryption is enabled for the seed instance in the
            cluster. If it cannot be enabled an error is raised.
          </p></li><li class="listitem"><p>
            Setting
            <code class="literal">createCluster({memberSslMode:'AUTO'})</code>
            (the default) then SSL encryption is automatically enabled
            if the server instance supports it, or disabled if the
            server does not support it.
</p></li></ul>
</div>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Note
</div>
<p>
          When using the commercial version of MySQL, SSL is enabled by
          default and you might need to configure the whitelist for all
          instances. See <a class="xref" href="mysql-innodb-cluster-userguide.html#create-whitelist-servers" title="Creating a Whitelist of Servers">Creating a Whitelist of Servers</a>.
</p>
</div>
<p>
        When you issue the <code class="literal">cluster.addInstance()</code> and
        <code class="literal">cluster.rejoinInstance()</code> commands, SSL
        encryption on the instance is enabled or disabled based on the
        setting found for the seed instance. For more control, the
        <code class="literal">cluster.addInstance()</code>, and
        <code class="literal">cluster.rejoinInstance()</code> commands accept the
        <code class="literal">memberSslMode</code> option. This can be used to
        test the SSL settings of the cluster when instances join. The
        behavior of the commands in this case is:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Setting <code class="literal">memberSslMode:'DISABLED'</code> ensures
            SSL encryption is disabled for the instance in the cluster.
          </p></li><li class="listitem"><p>
            Setting <code class="literal">memberSslMode:'REQUIRED'</code> forces
            SSL encryption to be enabled for the instance in the
            cluster.

            
          </p></li><li class="listitem"><p>
            Setting <code class="literal">memberSslMode:'AUTO'</code> (the
            default) then SSL encryption is automatically enabled or
            disabled based on the setting used by the seed instance
            (other members of the cluster) and the available SSL support
            provided by the instance itself.
</p></li></ul>
</div>
<p>
        When using <code class="literal">createCluster()</code> with the
        <code class="literal">adoptFromGR</code> option to adopt an existing Group
        Replication group, no SSL settings are changed on the adopted
        cluster:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">memberSslMode</code> cannot be used with
            <code class="literal">adoptFromGR</code>.
          </p></li><li class="listitem"><p>
            If the SSL settings of the adopted cluster are different
            from the ones supported by the MySQL Shell, in other words
            SSL for Group Replication recovery and Group Communication,
            both settings are not modified. This means you are not be
            able to add new instances to the cluster, unless you change
            the settings manually for the adopted cluster.
</p></li></ul>
</div>
<p>
        MySQL Shell always enables or disables SSL for the cluster for
        both Group Replication recovery and Group Communication, see
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="17.5.2 Secure Socket Layer Support (SSL)">Section 17.5.2, “Secure Socket Layer Support (SSL)”</a>.
        A verification is performed and an error issued in case those
        settings are different for the seed instance (for example as the
        result of a <code class="literal">dba.createCluster()</code> using
        <code class="literal">adoptFromGR</code>) when adding a new instance to
        the cluster. SSL encryption must be enabled or disabled for all
        instances in the cluster. Verifications are performed to ensure
        that this invariant holds when adding a new instance to the
        cluster.

        
      </p><p>
        The <code class="literal">deploySandboxInstance()</code> command attempts
        to deploy sandbox instances with SSL encryption support by
        default. If it is not possible, the server instance is deployed
        without SSL support. Use the <code class="literal">ignoreSslError</code>
        option set to false to ensure that sandbox instances are
        deployed with SSL support, issuing an error if SSL support
        cannot be provided. When <code class="literal">ignoreSslError</code> is
        true, which is the default, no error is issued during the
        operation if the SSL support cannot be provided and the server
        instance is deployed without SSL support.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="create-whitelist-servers"></a>Creating a Whitelist of Servers</h3>

</div>

</div>

</div>
<p>
        

        When using a cluster's <code class="literal">createCluster()</code>,
        <code class="literal">addInstance()</code>, and
        <code class="literal">rejoinInstance()</code> methods you can optionally
        specify a list of approved servers that belong to the cluster,
        referred to as a whitelist. By specifying the whitelist
        explicitly in this way you can increase the security of your
        cluster because only servers in the whitelist can connect to the
        cluster.

        

        By default, if not specified explicitly, the whitelist is
        automatically set to the private network addresses that the
        server has network interfaces on. To configure the whitelist,
        specify the servers to add with the
        <code class="literal">ipWhitelist</code> option when using the method.
        Pass the servers as a comma separated list, surrounded by
        quotes. Using the <code class="literal">ipWhitelist</code> option
        configures the
        <a class="link" href="group-replication.html#sysvar_group_replication_ip_whitelist"><code class="literal">group_replication_ip_whitelist</code></a>
        system variable on the instance. For example:
      </p><pre data-lang="mysqlsh" class="programlisting">
mysql-js&gt;<strong class="userinput"><code> cluster.addInstance("ic@ic-3:3306", {ipWhitelist: "203.0.113.0/24, 198.51.100.110"})</code></strong>
</pre><p>
        This configures the instance to only accept connections from
        servers at addresses <code class="literal">203.0.113.0/24</code> and
        <code class="literal">198.51.100.110</code>. From MySQL 5.7.21, the
        whitelist can also include host names, which are resolved only
        when a connection request is made by another server.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          Host names are inherently less secure than IP addresses in a
          whitelist. MySQL carries out FCrDNS verification, which
          provides a good level of protection, but can be compromised by
          certain types of attack. Specify host names in your whitelist
          only when strictly necessary, and ensure that all components
          used for name resolution, such as DNS servers, are maintained
          under your control. You can also implement name resolution
          locally using the hosts file, to avoid the use of external
          components.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="use-mysql-shell-execute-script"></a>Using MySQL Shell to Execute a Script</h3>

</div>

</div>

</div>
<p>
        You can automate cluster configuration with scripts. For
        example:
      </p><pre data-lang="terminal" class="programlisting">
shell&gt; <strong class="userinput"><code>mysqlsh -f <em class="replaceable"><code>setup-innodb-cluster.js</code></em></code></strong>
</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
          Any command line options specified after the script file name
          are passed to the script and <span class="emphasis"><em>not</em></span> to
          MySQL Shell. You can access those options using the
          <code class="literal">os.argv</code> array in JavaScript, or the
          <code class="literal">sys.argv</code> array in Python. In both cases,
          the first option picked up in the array is the script name.
</p>
</div>
<p>
        The contents of an example script file is shown here:
      </p><pre data-lang="js" class="programlisting">
  print('MySQL InnoDB cluster sandbox set up\n');
  print('==================================\n');
  print('Setting up a MySQL InnoDB cluster with 3 MySQL Server sandbox instances.\n');
  print('The instances will be installed in ~/mysql-sandboxes.\n');
  print('They will run on ports 3310, 3320 and 3330.\n\n');

  var dbPass = shell.prompt('Please enter a password for the MySQL root account: ', {type:"password"});

  try {
     print('\nDeploying the sandbox instances.');
     dba.deploySandboxInstance(3310, {password: dbPass});
     print('.');
     dba.deploySandboxInstance(3320, {password: dbPass});
     print('.');
     dba.deploySandboxInstance(3330, {password: dbPass});
     print('.\nSandbox instances deployed successfully.\n\n');

     print('Setting up InnoDB cluster...\n');
     shell.connect('root@localhost:3310', dbPass);

     var cluster = dba.createCluster("prodCluster");

     print('Adding instances to the cluster.');
     cluster.addInstance({user: "root", host: "localhost", port: 3320, password: dbPass});
     print('.');
     cluster.addInstance({user: "root", host: "localhost", port: 3330, password: dbPass});
     print('.\nInstances successfully added to the cluster.');

     print('\nInnoDB cluster deployed successfully.\n');
  } catch(e) {
     print('\nThe InnoDB cluster could not be created.\n\nError: ' +
     + e.message + '\n');
}</pre>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-limitations"></a>20.5 Known Limitations</h2>

</div>

</div>

</div>
<p>
      This section describes the known limitations of InnoDB cluster.
      As InnoDB cluster uses Group Replication, you should also be
      aware of its limitations, see
      <a class="xref" href="group-replication.html#group-replication-limitations" title="17.7.2 Group Replication Limitations">Section 17.7.2, “Group Replication Limitations”</a>.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          



          

          The formatting of results which contain multi-byte characters
          sometimes do not have correctly aligned columns. Similarly,
          non-standard character sets are being corrupted in results.
        </p></li><li class="listitem"><p>
          

          AdminAPI does not support Unix socket connections.
          MySQL Shell currently does not prevent you from attempting
          to use socket connections to a cluster, and attempting to use
          a socket connection to a cluster can cause unexpected results.
        </p></li><li class="listitem"><p>
          

          The MySQL Shell help describes an invalid URI:

</p><pre data-lang="simple" class="programlisting">USER[:PASS]@::SOCKET[/DB].</pre><p>

          This is invalid because the <code class="literal">@</code> symbol can
          not be present if no user information is provided.
        </p></li><li class="listitem"><p>
          

          If a session type is not specified when creating the global
          session, MySQL Shell provides automatic protocol detection
          which attempts to first create a NodeSession and if that fails
          it tries to create a ClassicSession. With an InnoDB cluster
          that consists of three server instances, where there is one
          read-write port and two read-only ports, this can cause
          MySQL Shell to only connect to one of the read-only
          instances. Therefore it is recommended to always specify the
          session type when creating the global session.
        </p></li><li class="listitem"><p>
          

          When adding non-sandbox server instances (instances which you
          have configured manually rather than using
          <code class="literal">dba.deploySandboxInstance()</code> ) to a cluster,
          MySQL Shell is not able to persist any configuration changes
          in the instance's configuration file. This leads to one or
          both of the following scenarios:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
              The Group Replication configuration is not persisted in
              the instance's configuration file and upon restart the
              instance does not rejoin the cluster.
            </p></li><li class="listitem"><p>
              The instance is not valid for cluster usage. Although the
              instance can be verified with
              <code class="literal">dba.checkInstanceConfiguration()</code>, and
              MySQL Shell makes the required configuration changes in
              order to make the instance ready for cluster usage, those
              changes are not persisted in the configuration file and so
              are lost once a restart happens.
</p></li></ol>
</div>
<p>
          If only <code class="literal">a</code> happens, the instance does not
          rejoin the cluster after a restart.
        </p><p>
          If <code class="literal">b</code> also happens, and you observe that the
          instance did not rejoin the cluster after a restart, you
          cannot use the recommended
          <code class="literal">dba.rebootClusterFromCompleteOutage()</code> in
          this situation to get the cluster back online. This is because
          the instance loses any configuration changes made by
          MySQL Shell, and because they were not persisted, the
          instance reverts to the previous state before being configured
          for the cluster. This causes Group Replication to stop
          responding, and eventually the command times out.
        </p><p>
          To avoid this problem it is strongly recommended to use
          <code class="literal">dba.configureLocalInstance()</code> before adding
          instances to a cluster in order to persist the configuration
          changes.
        </p></li><li class="listitem"><p>
          

          Using MySQL server instances configured with the
          validate_password plugin and password policy set to
          <code class="literal">STRONG</code> causes InnoDB cluster
          <code class="literal">createCluster()</code> and MySQL Router bootstrap
          operations to fail. This is because the internal user required
          for access to the server instance can not be validated.
        </p></li><li class="listitem"><p>
          

          The MySQL Router <code class="option">--bootstrap</code> command line option
          does not accept IPv6 addresses.
        </p></li><li class="listitem"><p>
          

          The commercial version of MySQL Router does not have the correct
          setting for AppArmor. A work around is to edit the AppArmor
          profile configuration file
          <code class="filename">/etc/apparmor.d/usr.sbin.mysqlrouter</code> and
          modify the line containing <code class="literal">/usr/sbin/mysqld</code>
          to use the path to MySQL Router, for example
          <code class="literal">/usr/sbin/mysqlrouter</code>.
        </p></li><li class="listitem"><p>
          

          Using the <code class="literal">adoptFromGR</code> option with the
          <code class="literal">dba.createCluster()</code> function to create a
          cluster based on an existing deployment of Group Replication
          fails with an error that the instance is already part of a
          replication group. This happens in MySQL Shell's
          default wizard mode only. A workaround is to disable wizard
          mode by launching <a class="link" href="programs.html#mysqlsh" title="4.5.7 mysqlsh — The MySQL Shell"><span class="command"><strong>mysqlsh</strong></span></a> with the
          <a class="link" href="programs.html#option_mysqlsh_no-wizard"><code class="option">--no-wizard</code></a> command option.
        </p></li><li class="listitem"><p>
          

          The use of the
          <a class="link" href="server-administration.html#option_mysqld_defaults-extra-file"><code class="option">--defaults-extra-file</code></a> option to
          specify an option file is not supported by InnoDB cluster
          server instances.
</p></li></ul>
</div>

</div>

</div>
<div class="copyright-footer">

</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="document-store.html">Prev</a></td>
<td width="20%" align="center"><a accesskey="u" href="">Up</a></td>
<td width="40%" align="right"> <a accesskey="n" href="mysql-cluster.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 19 Using MySQL as a Document Store</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">Chapter 21 MySQL NDB Cluster 7.5 and NDB Cluster 7.6</td>
</tr>
</table>
</div>
</body>
</html>
